/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package cn.ekuma.data.dao;

import cn.ekuma.data.dao.bean.IKeyed;
import cn.ekuma.data.dao.bean.I_BaseBean;
import cn.ekuma.data.dao.bean.I_ViewBean;
import com.openbravo.data.basic.BasicException;
import com.openbravo.data.loader.I_Session;
import com.openbravo.data.loader.KeyBuilder;
import com.openbravo.data.loader.TableDefinition;
import com.openbravo.data.loader.query.QBFParameter;
import com.openbravo.data.loader.query.QBFParameters;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 *
 * @author Administrator
 */
public abstract class DataLogic<D extends BaseDAO> implements I_DataLogic{
   protected I_Session s;
   protected Map<Class,D> daoMap=new HashMap<Class,D>();
   protected Map<Class,InfoDAO> infoDaoMap=new HashMap<Class,InfoDAO>();
   protected Map<Class,ViewDAO> viewDaoMap=new HashMap<Class,ViewDAO>();

   public DataLogic(I_Session s){
	   this.s=s;
   }

   public void  addDaoToMap(ViewDAO obj){
        if(obj instanceof BaseDAO<?>)
            daoMap.put(obj.getSuportClass(), (D) obj);
       else if(obj instanceof InfoDAO)
            infoDaoMap.put(obj.getSuportClass(), (InfoDAO) obj);
       else  
           viewDaoMap.put(obj.getSuportClass(), obj);
   }

   public ViewDAO getDao(Class c){
       ViewDAO d=viewDaoMap.get(c);
       if(d==null)
           d=infoDaoMap.get(c);
       if(d==null)
           d=daoMap.get(c);
       return d;
   }

   public int insert(I_BaseBean obj) throws BasicException{
        BaseDAO dao=daoMap.get(obj.getClass());
        if(dao==null)
            throw new BasicException("DAO no suport insert:"+obj.getClass());
        return dao.insert(obj);
    }

   
   public IKeyed insertAutoGenerator(I_BaseBean obj) throws BasicException{
	     insert(obj);
        return KeyBuilder.getBeanKey(obj);
   }
   
   
   
    public int update(I_BaseBean obj) throws BasicException{
        BaseDAO dao=daoMap.get(obj.getClass());
         if(dao==null)
            throw new BasicException("DAO no suport update:"+obj.getClass());
        return dao.update(obj);
        
    }

     public int delete(I_BaseBean obj) throws BasicException{
        BaseDAO dao=daoMap.get(obj.getClass());
        if(dao==null)
            throw new BasicException("DAO no suport delete:"+obj.getClass());
        return dao.delete((IKeyed)obj);
        
    }

     
     public int insertOrUpdate(I_BaseBean obj) throws BasicException{
         BaseDAO dao=daoMap.get(obj.getClass());
          if(dao==null)
             throw new BasicException("DAO no suport update:"+obj.getClass());
         return dao.insertOrUpdate(obj);
     }
     
     public int deleteByIKeyed(Class c,IKeyed k) throws BasicException{
        BaseDAO dao=daoMap.get(c);
         if(dao==null)
            throw new BasicException("DAO no suport delete:"+c);
        return dao.delete(k);
     }

    public int deleteObjs(List objs) throws BasicException {
        BaseDAO dao=daoMap.get(objs.get(0).getClass());
        if(dao==null)
            throw new BasicException("DAO no suport list delete:"+objs.get(0).getClass());
        return dao.delete(objs);
    }
    
    
    public int deleteByQBFParameters(Class c,QBFParameters filter) throws BasicException{
    	BaseDAO dao=daoMap.get(c);
        if(dao==null)
            throw new BasicException("DAO no suport list delete:"+c);
        return dao.delete(filter);
    }
 
    public int insertObjs(List objs) throws BasicException {
    	if(objs.isEmpty())
    		return 1;
         BaseDAO dao=daoMap.get(objs.get(0).getClass());
        if(dao==null)
            throw new BasicException("DAO no suport list insert:"+objs.get(0).getClass());
        return dao.insert(objs);
    }

    public int updateObjs(List objs) throws BasicException {
    	if(objs.isEmpty())
    		return 1;
        BaseDAO dao=daoMap.get(objs.get(0).getClass());
        if(dao==null)
            throw new BasicException("DAO no suport list update:"+objs.get(0).getClass());
        return dao.update(objs);
    }
    
    public int insertOrUpdate(List objs) throws BasicException {
    	if(objs.isEmpty())
    		return 1;
        BaseDAO dao=daoMap.get(objs.get(0).getClass());
        if(dao==null)
            throw new BasicException("DAO no suport list update:"+objs.get(0).getClass());
        return dao.insertOrUpdate(objs);
    }
    

    public I_ViewBean find(Class c, IKeyed id) throws BasicException {
        if(daoMap.containsKey(c))
            return (I_ViewBean)daoMap.get(c).find(id);
        else if(infoDaoMap.containsKey(c))
            return (I_ViewBean)infoDaoMap.get(c).find(id);
       throw new BasicException("DAO no suport find:"+c);
    }

    public I_ViewBean findByStringId(Class c, String id) throws BasicException {
        return find(c,KeyBuilder.getKey(id));
    }

    public I_ViewBean findByIntId(Class c, int id) throws BasicException {
        return find(c,KeyBuilder.getKey(id));
   }

     public List list(Class c) throws BasicException {
        if(daoMap.containsKey(c))
            return daoMap.get(c).list();
        else if(infoDaoMap.containsKey(c))
            return infoDaoMap.get(c).list();
        else if(viewDaoMap.containsKey(c))
            return viewDaoMap.get(c).list();
        throw new BasicException("DAO no suport list:"+c);
    }

     public List listByFilter(Class c,Object filter) throws BasicException {
        if(daoMap.containsKey(c))
            return daoMap.get(c).list(filter);
        else if(infoDaoMap.containsKey(c))
            return infoDaoMap.get(c).list(filter);
        else if(viewDaoMap.containsKey(c))
            return viewDaoMap.get(c).list(filter);
        throw new BasicException("DAO no suport list:"+c);
    }
     
     @Override
	public List query(Class c, QBFParameters filter) throws BasicException {
    	 if(daoMap.containsKey(c))
             return daoMap.get(c).query(filter);
         else if(infoDaoMap.containsKey(c))
             return infoDaoMap.get(c).query(filter);
         else if(viewDaoMap.containsKey(c))
             return viewDaoMap.get(c).query(filter);
         throw new BasicException("DAO no suport query:"+c);
	}
      

	@Override
	public List queryByQBFParameter(Class c, QBFParameter filter) throws BasicException {
		if(daoMap.containsKey(c))
            return daoMap.get(c).query(filter);
        else if(infoDaoMap.containsKey(c))
            return infoDaoMap.get(c).query(filter);
        else if(viewDaoMap.containsKey(c))
            return viewDaoMap.get(c).query(filter);
        throw new BasicException("DAO no suport query:"+c);
	}

	public List listByParent(Class c,final I_ParentNode parent)throws BasicException {
          if(daoMap.containsKey(c))
            return daoMap.get(c).list(new I_ParentNode<String>(){
                public IKeyed<String> getParentKey(){
                    return parent.getParentKey();
                }public Class getParentClass() {
                   return transParentClass(parent.getParentClass());
                }
            });
         throw new BasicException("DAO no suport list:"+c);
     }

    public List list(Class c, final Class parent, final String id) throws BasicException {
        return listByParent(c,new I_ParentNode<String>(){
            public IKeyed<String> getParentKey() {
                return KeyBuilder.getKey(id);
            }
            public Class getParentClass() {
               return parent;
            }
        });
    }

     @Override
	public int updateByFieldWithIKeyed(IKeyed obj, String field, Object newValue)throws BasicException {
     BaseDAO dao=daoMap.get(obj.getClass());
     if(dao==null)
         throw new BasicException("DAO no suport updateByField:"+obj.getClass());
     return dao.updateByField(obj, field, newValue);	
	}
     
    @Override
 	public int updateByField(Class c,IKeyed obj, String field, Object newValue)throws BasicException {
      BaseDAO dao=daoMap.get(c);
      if(dao==null)
          throw new BasicException("DAO no suport updateByField:"+obj.getClass());
      return dao.updateByField(obj, field, newValue);	
 	} 

	public TableDefinition getTableDefinition(Class c){
         BaseDAO dao=daoMap.get(c);
        if(dao!=null)
            return dao.getTableDefinition();
         return null;
     }

    public I_Session getSession() {
        return s;
    }
    
    public int clear(Class c)throws BasicException {
    	BaseDAO dao=daoMap.get(c);
        if(dao==null)
           throw new BasicException("DAO no suport delete:"+c);
       return dao.clear();
    }

	@Override
	public List listByFilterWithClassName(String c, Object filter)
			throws BasicException {
		Class cs;
		try {
			cs = Class.forName(c);
		} catch (ClassNotFoundException e) {
			throw new BasicException("DAO no suport updateByField:"+c);
		}	
		return listByFilter(cs,filter);
	}

	@Override
	public List listWithClassName(String c) throws BasicException {
		Class cs;
		try {
			cs = Class.forName(c);
		} catch (ClassNotFoundException e) {
			throw new BasicException("DAO no suport updateByField:"+c);
		}	
		return list(cs);
	}

	@Override
	public List listWithParentClassAndKey(String c, String parent, String id)
			throws BasicException {
		Class cs,parent1;
		try {
			cs = Class.forName(c);
			parent1= Class.forName(parent);
		} catch (ClassNotFoundException e) {
			throw new BasicException("DAO no suport updateByField:"+c);
		}	
		return list(cs,parent1,id);
	}

	@Override
	public List queryByQBFParameters(String c, QBFParameters filter)throws BasicException{
	Class cs;
	try {
		cs = Class.forName(c);
	} catch (ClassNotFoundException e) {
		throw new BasicException("DAO no suport updateByField:"+c);
	}	
	return query(cs,filter);
	}
	
	
	public abstract Class transParentClass(Class in);

	@Override
	public List listWithDateTime(Class c, Date start, Date end)
			throws BasicException {
		I_DataTimeListSuport listDao = null;
		 if(daoMap.containsKey(c)){
			 BaseDAO dao=daoMap.get(c);
			 if(dao instanceof I_DataTimeListSuport)
				 listDao=(I_DataTimeListSuport)dao;
			 else
				return dao.list();
		 }else if(infoDaoMap.containsKey(c)){
			 InfoDAO dao=infoDaoMap.get(c);
			 if(dao instanceof I_DataTimeListSuport)
				 listDao=(I_DataTimeListSuport)dao;
			 else
				return dao.list();
		 }else if(viewDaoMap.containsKey(c)){
			 ViewDAO dao=viewDaoMap.get(c);
			 if(dao instanceof I_DataTimeListSuport)
				 listDao=(I_DataTimeListSuport)dao;
			 else
				return dao.list();
		 }
        if(listDao==null)    
            throw new BasicException("DAO no suport query:"+c);    
		return listDao.listWithTime(start, end);
	}

	@Override
	public List listWithDateTimeByClassName(String c,Date start, Date end)
			throws BasicException {
		Class cs;
		try {
			cs = Class.forName(c);
		} catch (ClassNotFoundException e) {
			throw new BasicException("DAO no suport updateByField:"+c);
		}	
		return listWithDateTime(cs,start,end);
	}

	@Override
	public boolean isExistByField(Class c, String field, Object value)
			throws BasicException {
		BaseDAO dao=daoMap.get(c);
        if(dao==null)
           throw new BasicException("DAO no suport delete:"+c);
		return dao.isExistByField(field, value);
	}

	public boolean isExistByFields(Class c, String[] fields, Object[] values)
			throws BasicException {
		BaseDAO dao=daoMap.get(c);
        if(dao==null)
           throw new BasicException("DAO no suport delete:"+c);
		return dao.isExistByFields(fields, values);
	}
	
}
